package com.example.tanloadpic;

import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;



import androidx.annotation.NonNull;
import com.example.tanloadpic.handle.RequestHandler;
import com.example.tanloadpic.handle.impl.FileStreamHandler;
import com.example.tanloadpic.handle.impl.MemoryCacheHandler;
import com.example.tanloadpic.handle.impl.NetWorkHandler;
import com.example.tanloadpic.handle.impl.ResourceHandler;


import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


import static com.example.tanloadpic.utils.constant.LIFO;
import static com.example.tanloadpic.utils.constant.REQUEST_HANDLE_FAIL;
import static com.example.tanloadpic.utils.constant.REQUEST_HANDLE_SUCCESS;


public class TanLoadPic {
    public static volatile TanLoadPic instance;

    private int totalTaskNum;
    public Dispatcher mDispatcher;
    public Context mContext;

    public MemoryCaches mMemoryCache;

    List<RequestHandler> mRequestHandlerList;
    ExecutorService mService;

    int mMode;
    private HashSet<BitmapHunter> mFailSet;

    private TanLoadPic() {
    }

    public TanLoadPic(Dispatcher mDispatcher, Context mContext, MemoryCaches mMemoryCache,
                      List<RequestHandler> mRequestHandlerList, ExecutorService mService,
                      int mMode, HashSet<BitmapHunter> mFailSet) {
        this.mDispatcher = mDispatcher;
        this.mContext = mContext;
        this.mMemoryCache = mMemoryCache;

        this.mRequestHandlerList = mRequestHandlerList;
        this.mService = mService;
        this.mMode = mMode;
        this.mFailSet = mFailSet;
    }

    public static TanLoadPic get(Context context) {
        if (instance == null) {
            synchronized (TanLoadPic.class) {
                if (instance == null) {
                    instance = new Builder(context).build();
                }
            }
        }
        return instance;
    }

    public RequestCreator load(Uri uri) {
        return new RequestCreator(this, uri);
    }

    public void startExecute(RequestData requestData) {
        totalTaskNum++;
        mDispatcher.doOut(requestData);
    }


    public static class Builder {
        private final Context context;
        private ExecutorService executorService;
        public int mode;
        public MemoryCaches memoryCaches;
        private List<RequestHandler> requestHandlerList;
        private HashSet<BitmapHunter> failSet;
        private  Dispatcher dispatcher;

        public Builder(Context context) {
            if (context == null) {
                throw new NullPointerException("兄弟，请注意哦，上下文为空了");
            }
            this.context = context;

        }

        public TanLoadPic build() {
            if (executorService == null) {
                executorService = new ThreadPoolExecutor(6, 6, 0, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

            }
            if (mode == 0) {
                mode = LIFO;
            }


            if (memoryCaches == null) {

                memoryCaches = new memoryCachesImpl();
            }
            requestHandlerList = new ArrayList<>();
            requestHandlerList.add(new MemoryCacheHandler());
            requestHandlerList.add(new FileStreamHandler());
            requestHandlerList.add(new ResourceHandler());
            requestHandlerList.add(new NetWorkHandler());
            dispatcher = new Dispatcher(mainHandler,executorService,mode);
            return new TanLoadPic(dispatcher,context,memoryCaches,requestHandlerList,executorService,mode,failSet);
        }

    }



    static final Handler mainHandler = new Handler(Looper.getMainLooper()) {
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case REQUEST_HANDLE_SUCCESS:

                    BitmapHunter hunterSuccess = (BitmapHunter) msg.obj;
                    hunterSuccess.mTanLoadPic.setBitmap(hunterSuccess);
                    break;
                case REQUEST_HANDLE_FAIL:

                    BitmapHunter hunterFail = (BitmapHunter) msg.obj;
                    hunterFail.mTanLoadPic.requestFail(hunterFail);
                    break;
            }
        }
    };

    private void requestFail(BitmapHunter hunterFail) {


    }

    private void setBitmap(BitmapHunter hunterSuccess) {
        hunterSuccess.mData.imageView.setImageBitmap(hunterSuccess.getBitmapResult());
    }


}
